import createApp from './app';

export default context => {
  return new Promise((resolve, reject) => {
    const { app, router, store } = createApp();
    // context: 服务端执行renderToString时传递的对象，通常有url和其他参数

    context.ctxLogger.info(`entry-server url: ${context.url}`);
    router.push(context.url);

    router.onReady(() => {
      const matchedComponents = router.getMatchedComponents();
      // console.log('_________matchedComponents', matchedComponents.length);
      // console.log('_________context cookie', context.cookie);

      context.ctxLogger.info(`entry-server url: ${context.url}, matchedComponents: ${matchedComponents.length}`);
      if (!matchedComponents.length) {
        return reject({ code: 404 }); // 服务端渲染时需要捕捉该错误，或者push 404
      }

      // console.log('________entry-server userInfo', router.currentRoute);
      // 服务端获取到的userInfo存入前端store
      store.state.userInfo = context.userInfo;
      store.state.redirectUrl = context.redirectUrl;
      if (router.currentRoute.meta) {
        store.state.title = router.currentRoute.meta.title;
      }
      context.state = store.state;

      // 对所有匹配的路由组件调用 `asyncData()`
      Promise.all(matchedComponents.map(Component => {
        if (Component && Component.asyncData) {
          return Component.asyncData({
            store,
            route: router.currentRoute,
            cookie: context.cookie,
            ctxLogger: context.ctxLogger
          }).catch(err => { // 某一个请求异常了，也resolve
            context.ctxLogger.error(`entry-server component asyncData err. url: ${context.url}`, err);
            return { returnCode: '-9999' };
          });
        }
      })).then(() => {
        // 注入meta
        context.meta = app.$meta();

        // 在所有预取钩子(preFetch hook) resolve 后，
        // 我们的 store 现在已经填充入渲染应用程序所需的状态。
        // 当我们将状态附加到上下文，
        // 并且 `template` 选项用于 renderer 时，
        // 状态将自动序列化为 `window.__INITIAL_STATE__`，并注入 HTML。

        resolve(app);
      }).catch((err) => {
        context.ctxLogger.error(`entry-server asyncData err. url: ${context.url}`, err);
        reject(err); // 服务端渲染时需要捕捉该错误
      });
    }, (err) => {
      context.ctxLogger.error(`entry-server router onready err. url: ${context.url}`, err);
      reject(err); // 服务端渲染时需要捕捉该错误
    });
  });
};
